import { Input, InputRef, message, Modal } from 'antd';
import {
  forwardRef,
  useEffect,
  useImperativeHandle,
  useMemo,
  useRef,
  useState,
} from 'react';
import EditableTable from '../EditableTable';
import './index.less';
import { useForm } from '@formily/react';
import { getMessage, TextWidget } from '@inbiz/react';
import { getApi, getMethodKeyData } from './service';
import OutputTable from './OutputTable';
import ServerModal, { DataType } from './ServerModal';
import { uuid } from '@inbiz/utils';
import titleSvg from './svg/title.svg';
import { ControllerInput } from './ControllerInput';

type InputDataType = {
  Describe: string;
  Name: string;
  Value: any;
  ControlVar: any;
  key: string;
  Type: 0 | 1 | 2 | 3;
  Description?: string;
};

type IQueryModalContentProps = {
  modalTitle?: string;
  queryData: any;
  type: ('search' | 'edit' | 'delete')[];
  resultKeys?: string[];
  isPrimaryKey?: boolean;
  variableOptions?: string[] | { label: string; value: string }[];
  isController?: boolean
  // setSingleValue?: (data: {label: string, value: string}[]) => void;
  // singleValue?: {label: string, value: string}[];
};

const QueryModalContent = (props: IQueryModalContentProps, ref: any) => {
  const { modalTitle, queryData } = props;

  const form = useForm();
  const { appInfo } = form as unknown as { appInfo: { appId: string } };
  const outRef = useRef<{
    outDataSource: any[];
    setOutDataSource: (data: any[]) => void;
  }>(null);
  const inputConfigRef = useRef<{ getDataSource: () => any[] }>(null);
  const columns = useMemo(() => {
    let options: { label: string; value: string }[] = [];
    if (props.variableOptions) {
      if (typeof props.variableOptions[0] == 'string') {
        options = props.variableOptions.map((item) => ({
          label: item,
          value: item,
        })) as {
          label: string;
          value: string;
        }[];
      } else {
        options = props.variableOptions as { label: string; value: string }[];
      }
    }
    return [
      {
        dataIndex: 'Name',
        title: getMessage('ApiQuery.parameterName'),
        key: 'Name',
        width: 184,
        ellipsis: true,
        editData: {
          beforEdit: () => {
            return false;
          },
          type: 'Input',
        },
        render: (value: any) => {
          return <span title={value}>{value}</span>;
        },
      },
      {
        dataIndex: 'Value',
        title: getMessage('ApiQuery.defaultValue'),
        key: 'Value',
        width: 184,
        ellipsis: true,
        editData: {
          type: 'Input',
        },
        render: (value: any) => {
          return <span title={value}>{value}</span>;
        },
      },
      {
        dataIndex: 'Type',
        title: getMessage('ApiQuery.origin'),
        key: 'Type',
        width: 110,
        ellipsis: true,
        editData: {
          beforEdit: () => {
            return false;
          },
          type: 'Input',
        },
        render: (value: any) => {
          const title =
            value === 0
              ? 'HeaderParms'
              : value === 1
              ? 'BodyParms'
              : value === 2
              ? 'PathParms'
              : 'QueryParms';
          return <span title={title}>{title}</span>;
        },
      },
      props.isController ? undefined : {
        dataIndex: 'Describe',
        title: getMessage('ApiQuery.parameterDescription'),
        key: 'Describe',
        ellipsis: true,
        width: 293,
        editData: {
          beforEdit: () => {
            return false;
          },
          type: 'Input',
        },
        render: (value: any) => {
          return <span title={value}>{value}</span>;
        },
      },
      {
        dataIndex: 'ControlVar',
        title: getMessage('ApiQuery.controlVar'),
        key: 'ControlVar',
        width: 180,
        editData: {
          type: props.isController ? ControllerInput : 'AutoComplete',
          options,
          inTable: true
        },
      },
    ].filter(item => !!item);
  }, [props.variableOptions]);

  const inputRef = useRef<InputRef>(null);
  const serverRef = useRef<{
    selectData: any[];
    setSelectData: (data: any[]) => void;
  }>(null);
  const [visible, setVisible] = useState<boolean>(false); //弹窗开关
  const [inputValue, setInputValue] = useState<string>(); //选中接口input的值
  const [inputData, setInputData] = useState<InputDataType[]>([]); //入参数据
  const [selectDatas, setSelectDatas] = useState<DataType[]>([]); //选中的接口
  const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]); //表格选中的行
  const [change, setChange] = useState(false);

  useImperativeHandle(
    ref,
    () => ({
      getQueryContentData: () => {
        return {
          inputData: inputConfigRef.current?.getDataSource(),
          selectDatas,
          outData: outRef.current?.outDataSource,
        };
      },
    }),
    [inputData, selectDatas, outRef.current?.outDataSource],
  );

  const handleOk = () => {
    if (!serverRef.current?.selectData.length) {
      message.destroy();
      message.error(getMessage('ApiQuery.selectApiErr'));
      return;
    }
    setChange(true);
    setSelectDatas(serverRef.current?.selectData || []);
    outRef.current?.setOutDataSource([]);
    setInputValue(serverRef.current?.selectData?.[0].MethodName);
    setVisible(false);
  };

  const handleCancel = () => {
    setVisible(false);
    serverRef.current?.setSelectData([]);
    setSelectedRowKeys([selectDatas[0]?.key]);
  };

  useEffect(() => {
    if (selectDatas.length) {
      getApi({ MethodKey: selectDatas?.[0]?.key, appId: appInfo.appId }).then(
        (res) => {
          if (!queryData?.Key) {
            setInputData((old) => {
              let data: InputDataType[] = [];
              for (let k in res) {
                res[k].forEach((item: InputDataType) => {
                  data.push({
                    Name: item.Name,
                    Describe: item.Description || '',
                    Value: item.Value,
                    ControlVar: '',
                    key: uuid(8, 62),
                    Type:
                      k === 'HeaderParms'
                        ? 0
                        : k === 'BodyParms'
                        ? 1
                        : k === 'PathParms'
                        ? 2
                        : 3,
                  });
                });
              }
              let oldData = [...data];
              return oldData;
            });
          } else {
            if (change) {
              setInputData((old) => {
                let data: InputDataType[] = [];
                for (let k in res) {
                  res[k].forEach((item: InputDataType) => {
                    data.push({
                      Name: item.Name,
                      Describe: item.Description || '',
                      Value: item.Value,
                      ControlVar: '',
                      key: uuid(8, 62),
                      Type:
                        k === 'HeaderParms'
                          ? 0
                          : k === 'BodyParms'
                          ? 1
                          : k === 'PathParms'
                          ? 2
                          : 3,
                    });
                  });
                }
                let oldData = [...data];
                setChange(false);
                return oldData;
              });
            }
          }
        },
      );
    }
  }, [selectDatas]);

  const tryString = (value: string) => {
    if (value) {
      try {
        return JSON.parse(value?.replace(/\n/g, ''));
      } catch {
        return eval('(' + value + ')');
      }
    } else {
      return value;
    }
  };

  useEffect(() => {
    if (queryData) {
      if (queryData?.Key) {
        getMethodKeyData({
          appId: appInfo.appId,
          methodKey: queryData?.Key,
        }).then((res) => {
          if (res.status === 204) {
            message.destroy();
            message.error(<TextWidget>ApiQuery.apiDeleted</TextWidget>);
            // 后续清空入参及出参配置，包括查询及编辑tab页
            setSelectDatas([]);
            setInputValue('');
            setSelectedRowKeys([]);
            setInputData([]);
            outRef.current?.setOutDataSource([]);
          } else {
            setSelectDatas([
              {
                MethodName: res.MethodName,
                Remark: res.Remark,
                key: res.MethodKey,
                ServerKey: res.ServerKey,
                OutParm: tryString(res.DataPath),
                MethodKey: res.MethodKey,
                Id: res.Id,
              },
            ]);
            setInputValue(res.MethodName);
            setSelectedRowKeys([res.MethodKey]);
          }
        });
        setInputData(
          queryData?.InputConfig?.map((v: any) => {
            return { ...v, key: uuid(8, 62) };
          }),
        );
        outRef.current?.setOutDataSource(
          queryData?.OutConfig?.map((item: any) => {
            let old = { ...item, key: uuid(8, 62) };

            if (item.Childrens) {
              old.children = item.Childrens.map((v: any) => ({
                ...v,
                key: uuid(8, 62),
              }));
            }

            return old;
          }),
        );
      }
    }
  }, [queryData]);

  return (
    <div className="queryModal">
      <div
        className={`${
          modalTitle === 'search'
            ? 'queryModalList'
            : 'queryModalList queryModalListeditor'
        }`}
      >
        <div className="modalSearchContent">
          <span>
            <TextWidget>ApiQuery.selectApi</TextWidget>
          </span>
          <Input
            onClick={() => setVisible(true)}
            onFocus={() => inputRef.current?.blur()}
            ref={inputRef}
            value={inputValue}
          ></Input>
        </div>
        <div className="inputConfigContent">
          <div className="inputConfigText customApiOption-title">
            <img src={titleSvg} />
            <TextWidget>ApiQuery.inputConfig</TextWidget>
          </div>
          <div>
            <EditableTable
              //@ts-ignore
              columns={columns}
              addBtn={false}
              deleteBtn={false}
              ref={inputConfigRef}
              isRowSelection={false}
              dataSource={inputData}
              disableDraggable={true}
            />
          </div>
        </div>
        {props.resultKeys?.length && (
          <div className="outputConfigContent">
            <div className="outputConfigText customApiOption-title">
              <img src={titleSvg} />
              <TextWidget>ApiQuery.outputConfig</TextWidget>
            </div>
            <OutputTable
              modalTitle={modalTitle}
              selectDatas={selectDatas}
              ref={outRef}
              resultKeys={props.resultKeys}
              isPrimaryKey={props.isPrimaryKey}
            />
          </div>
        )}
        <Modal
          title={<TextWidget>ApiQuery.selectApi</TextWidget>}
          visible={visible}
          okText={<TextWidget>ApiQuery.ok</TextWidget>}
          cancelText={<TextWidget>ApiQuery.cancel</TextWidget>}
          destroyOnClose
          onOk={handleOk}
          onCancel={handleCancel}
          width={800}
          className="serverQueryModal"
          keyboard={false}
          maskClosable={false}
        >
          <ServerModal
            ref={serverRef}
            selectDatas={selectDatas}
            selectedRowKeys={selectedRowKeys}
            setSelectedRowKeys={setSelectedRowKeys}
          />
        </Modal>
      </div>
    </div>
  );
};

export default forwardRef(QueryModalContent);
